package com.atguigu.tingshu.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"all"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitService rabbitService;

    //获取声音的上次跳出时间
    @Override
    public BigDecimal getTrackBreakSecond(Long userId, Long trackId) {
        UserListenProcess userListenProcess = getMongoUserListenProcess(userId, trackId);
        if (userListenProcess != null) {
            return userListenProcess.getBreakSecond();
        }

        return new BigDecimal("0");
    }

    @Override
    public void updateListenProcess(Long userId, UserListenProcessVo userListenProcessVo) {
        //根据trackId和用户Id查询
        UserListenProcess userListenProcess = getMongoUserListenProcess(userId, userListenProcessVo.getTrackId());
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
        //如果可以查到数据，代表有播放进度，进行更新
        if (userListenProcess != null) {
            userListenProcess.setUpdateTime(new Date());
            //前端传入的时间数据
            userListenProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
            mongoTemplate.save(userListenProcess, collectionName);
        } else {
            //如果不能查询到数据，第一次播放，进行保存
            userListenProcess = new UserListenProcess();
            //修改属性
            BeanUtils.copyProperties(userListenProcessVo, userListenProcess);
            userListenProcess.setId(ObjectId.get().toString());
            userListenProcess.setUserId(userId);
            userListenProcess.setIsShow(1);
            userListenProcess.setCreateTime(new Date());
            userListenProcess.setUpdateTime(new Date());

            mongoTemplate.save(userListenProcess, collectionName);
        }

        //更新播放量 同一个用户24小时内播放算一次播放量
        //使用redis  setnx+过期时间
        //key是用户key+声音id 需要加trackId因为一个用户可能存多个收听声音的时间记录
        String key = "playnum_" + userId + userListenProcessVo.getTrackId();
        Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent(key, userListenProcessVo.getTrackId(), 24, TimeUnit.HOURS);

        if (ifAbsent) {
            //添加成功为第一次播放 更新播放量
            TrackStatMqVo trackStatMqVo = new TrackStatMqVo();

            trackStatMqVo.setBusinessNo(UUID.randomUUID().toString().replaceAll("-", ""));
            trackStatMqVo.setAlbumId(userListenProcessVo.getAlbumId());
            trackStatMqVo.setTrackId(userListenProcessVo.getTrackId());
            trackStatMqVo.setStatType(SystemConstant.TRACK_STAT_PLAY);
            trackStatMqVo.setCount(1);

            //发消息 传递需要更新播放量的Vo对象
            rabbitService.sendMessage(MqConst.EXCHANGE_TRACK, MqConst.ROUTING_TRACK_STAT_UPDATE, JSON.toJSONString(trackStatMqVo));
        }
    }

    //通过userId和trackId获取封装好的 mongoDB对应的 UserListenProcess对象
    private UserListenProcess getMongoUserListenProcess(Long userId, Long trackId) {
        //条件
        Query query = Query.query(Criteria.where("userId").is(userId).and("trackId").is(trackId));
        //找到用户对应的集合的名
        String collectionName = MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
        //mongoDB对应的对象
        return mongoTemplate.findOne(query, UserListenProcess.class, collectionName);
    }
}
